Cameras, cutscene setup, and ways to increase the longevity of your maps
Tutorial for ZDoom
By Ethan Watson aka GooberMan
Last Updated 15th January 2001 21:45

This article assumes general ZDoom editing knowledge, ACS scripting knowledge, and basic DeHackEd knowledge.
This article started out as a camera and cutscene setup tutorial. I have also included ways to increase the longevity of your maps because in a way they are interlinked. Throughout this article, I have provided ideas that I learnt while making Doom - The Arcade Game and ideas that I have yet to implement in the said project.

Section 1: Introduction to the basic ideas

Quick description of cameras in ZDoom (skip if you know the basics about cameras):

Cameras are being used more and more in modern games as an alternative to pre-rendered cut scenes. The advantage of cameras is that you don't have to break the immersion factor of a game by jumping to a pre-rendered cut scene of a quality 100 times better than the game engine itself. The disadvantage is the direct flip side of that - the quality is only as good as the engine allows. The Doom source port, ZDoom, has cameras included. The cameras are placed inside a map as a thing. There are several types of cameras that can be used, as will be discussed later on.


Quick word on thing flags and skill paths:

Flags are usually underused when it comes to things that aren't enemies or items. Just for a quick example, make up a small map. Include a teleporter which teleports to a Teleport Destination with a TID of 1. Include three Teleport destinations and place them in different positions in the map. Assign every one of them a TID of 1, and change each of their flags so one shows up in easy, one in medium, and one in hard. That example is severely underused in maps, and can not only increase the longevity of maps, but it also allows you to set up easier paths for easier skill levels.
The same goes for cameras. You can include three cameras of TID 1, and depending on which skill level you're on will depend on which camera you view things from when you switch to that camera. Again, useful if you're setting up easier paths and you wish to show the player a different thing dependant on difficulty level.
To further enhance these ideas, you can even close off whole sections of a level with some OPEN scripts. This is best seen in my Doom - The Arcade Game's MAP90, where not only whole sections are closed off, but the marines follow different path nodes.


Section 2: Description of things

Basic Cameras:

Thing number 9025: Security Camera

Security cameras are perhaps the simplest type of cameras in ZDoom. These are the perfect cameras to use if you just want one view of something in a cutscene. Just leave all the arguments at 0 (except for pitch if you wish) and you have a perfect non-moving camera. Of course, Security Cameras can be used as their name sake, and there are arguments which deal with this.

Argument :-             1 - Pitch
                          - Pitch is measured in conventional degrees. 0 is straight. 1-89 aim down. 166-255 aim up, with 166 being straight up.
                        2 - Turning Arc
                          - Turning Arc is measured in conventional degress. This argument defines how many degrees to each side of it's original angle a camera should turn each cycle.
                        3 - Cycle
                          - Cycle is measured in octics.

Thing number 9073: Aiming Camera

Similar to a Security Camera. These cameras follow a thing designated by a TID and argument 4.

Argument :-             1 - Pitch
                          - Pitch is measured in conventional degrees.
                        2 - Maximum horizontal turn
                          - This is measured in conventional degrees. Defines how far a camera is allowed to turn horizontally from it's original angle when following a thing.
                        3 - Maximum vertical turn
                          - This is measured in conventional degrees. Defines how far a camera is allowed to turn vertically from it's original pitch when following a thing.
                        4 - TID
                            This is the thing that the camera should follow. It is the same TID as the thing it is following.


Interpolation points:

Interpolation points are used by path followers. Interpolation points are almost the same as the path node things (thing 9024). Interpolation points define the path that path followers take. Setting up a path works just like setting up monster routes with path nodes - assign each interpolation point a different TID and set up your path from there.

Thing Number 9070: Interpolation point.

Argument :-             1 - Pitch
                          - Pitch is measured in conventional degrees.
                        2 - Time to reach this point from previous point
                          - This is measured in octics.
                        3 - Time to wait at point before moving to next point
                          - This is measured in octics.
                        4 - Low byte of next point's TID
                        5 - High byte of next point's TID
                          - This is a quick hack which allows for more than 255 points (a limit imposed on path nodes). Low byte is just like a normal TID (0-255). High byte allows for TIDs higher than 255, for example, if low was 0 and high was 1, the next point in the path would be TID 256; if low was 9 and high was 2, the next point in the path would be 521; etc. Here's a quick formula that should help you out: Next TID = (High x 256) + Low.

Thing Number 9075: Interpolation special

Interpolation specials allow specials to be activated when a path follower reaches a certain interpolation point. Set the TID of the interpolation special to the same TID of the interpolation point where you want the special to take place. Once this is done, you can assign a normal special to the interpolation special. For example, if you want a path follower to activate a door when it reaches a point with TID 5, you assign the interpolation special a TID of 5, special of Door_Raise, and the arguments that normally go with the Door_Raise special.


Path Followers:

Path followers are a class of things which follow interpolation points. You can compare them to monsters which follow path nodes (thing 9024). Each path follower shares the following arguments.

Argument :-             1 - Low byte of TID of first point in path
                        2 - High byte of TID of first point in path
                          - Refer to the Low/High byte description in the Interpolation point (Thing Number 9070) description.
                        3 - Behaviour bits
                          - This argument defines how a path follower moves when it moves along the path set up by interpolation points. To find the exact value you need, you just add the value/s supplied with the description of the bit together to get the integer value you need, or you can refer to the table below.
                          Bit descriptions:
                          Bit 1 (value = 1) - Follow a linear path compared to a curved path.
                          - By default, path followers move along a path in a curve rather than a straight line. This is especially handy for moving cameras, as you can define a nice sweeping arc of the area you want to view with only a handful of interpolation points. If you wish to use a curved path, you need at least 4 points. ZDoom uses the first and last points to calculate the curve that the camera uses, so in effect your camera will start at the second point and finish at the second last point. If the path defined is looping, it will start at the first point and calculate the curve using the last point.
                          Bit 2 (value = 2) - Adjust angle
                          - Changes the angle of the path follower to that of the interpolation point.
                          Bit 3 (value = 4) - Adjust pitch
                          - Changes the pitch of the path follower to that of the interpolation point.
                          Bit 4 (value = 8) - Aim in direction of motion
                          - Again, this one comes in handy for cameras. Instead of using the angle and pitch of the interpolation point, you can set this bit and the camera will aim in the direction it is moving, for example, if it is moving up and right, the camera will look up and right.

Bit table:
 _________________________________________________
| Linear | Adjust | Adjust | Aim in dir | |  Bits |
|  Path  |  Angle |  Pitch |  of motion | | Equal |
|-------------------------------------------------|
|   No   |   No   |   No   |     No     | |   0   |
|-------------------------------------------------|
|   Yes  |   No   |   No   |     No     | |   1   |
|-------------------------------------------------|
|   No   |   Yes  |   No   |     No     | |   2   |
|-------------------------------------------------|
|   Yes  |   Yes  |   No   |     No     | |   3   |
|-------------------------------------------------|
|   No   |   No   |   Yes  |     No     | |   4   |
|-------------------------------------------------|
|   Yes  |   No   |   Yes  |     No     | |   5   |
|-------------------------------------------------|
|   No   |   Yes  |   Yes  |     No     | |   6   |
|-------------------------------------------------|
|   Yes  |   Yes  |   Yes  |     No     | |   7   |
|-------------------------------------------------|
|   No   |   No   |   No   |     Yes    | |   8   |
|-------------------------------------------------|
|   Yes  |   No   |   No   |     Yes    | |   9*  | 
|-------------------------------------------------| 
|   No   |   Yes  |   No   |     Yes    | |   10* | 
|-------------------------------------------------|
|   Yes  |   Yes  |   No   |     Yes    | |   11* |
|-------------------------------------------------|
|   No   |   No   |   Yes  |     Yes    | |   12* |
|-------------------------------------------------|
|   Yes  |   No   |   Yes  |     Yes    | |   13* |
|-------------------------------------------------|
|   No   |   Yes  |   Yes  |     Yes    | |   14* |
|-------------------------------------------------|
|   Yes  |   Yes  |   Yes  |     Yes    | |   15* |
|_________________________________________________|

*NOTE: Not sure if these values are needed, but am
putting them there just in case.

Thing Number 9072: Moving Camera

Moving cameras are of the path follower class. As well as the standard arguments, a moving camera has the following additional arguments.

Argument :-             4 - TID
                          - This is the TID that the camera should look at while it is moving. Please not that it only looks at it on the horizontal plane and not the vertical plane, ie the camera only adjusts it's angle to look at it, not it's pitch.

Thing Number 9074: Actor Mover

Actor movers are of the path follower class. Using this special path follower, you can move any thing along the path. Assign the thing you wish to move a TID and set it's bits to dormant. When you want to move the thing along the path, activate the Actor mover. When you want it to stop following the path, deactivate the Actor mover. Do not activate/deactivate the thing you wish to move as this will not work, only activate/deactivate the Actor mover. As well as the standard arguments, an actor mover has the following additional arguments.

Argument :-             3 - Extra bits
                          Bit 7 (value = 64) - Make the moving thing nonsolid
                          - If you want the thing that is moving to go through walls for example, set this bit.
                        4 - TID
                          - This is the TID that the Actor mover controls.


Section 3: So how do I put all this in to a cutscene?

For the first example, lets say that the goal for a level would be to obtain a certain object. This object is raised on a pedestal. When you enter the map, you want to show the player the goal. A static camera looks OK but you know that you can do something better. Why not give the player a sweeping view of the room while keeping the camera's focus on the object at all times? This may sound challenging but is in fact very easy to do. I have included an example wad to display this map called CAMEX1.WAD. After seeing it, I decided that all it needed was some obstacles before you get to the key, a rolling boulder and a whole heap of natives once you escape the boulder and I'd have a re-enactment of Raiders Of The Lost Ark...
First of all, make the pedestal and place the object on it, say for example's sake the Yellow Skull Key. Assign the key a TID of 1. Next, insert a Moving Camera (thing number 9072). Assign it a TID of 2. Since the first interpolation point that we will be using will be assigned a TID of 3, set the first argument of the Moving Camera to 3. The only other argument needed in this example is the fourth argument. Set this to 1. The fourth argument tells the moving camera what TID it should focus on. Next it's time to set up some interpolation points. We will be using 4 points, the first point with a TID of 3 and the final point with a TID of 6. Place these points 128 units away from the key in all polar directions. This way, there will be a point above, below, and to the left and right of the key when looking at it in the editor. The arguments for the interpolation points now need to be set. Starting with TID 3, set the second argument to 30 and the fourth argument to 4. 30 is the amount of octics (1 tic = 1/35th of a second, 1 octic = 1 tic * 8) that the camera will take to get to this point from the previous point, while the 4 is the TID of the next point. Do the same with TID 4 except change the fourth argument to 5 (the next point after 4), change TID 5's fourth argument to 6, and change TID 6's argument to 3. This way, once the camera gets to point 6 it will immediately move to the starting point (TID 3). The camera and it's path is now successfully set up.
Next, to activate the camera when the player enters the level, you need to set up an OPEN script in ACS. I have provided an example script as follows:

script 1 OPEN {
   Thing_Deactivate (2);
   Thing_Activate (2);
   ChangeCamera (2, 0, 1);
}

I have included Thing_Deactivate and Thing_Activate because cameras are always active from the moment the map starts. If you change to a camera in the middle of a map and if you don't deactivate and reactivate the camera you will change cameras in to the middle of a loop or the end of a sequence depending on what you have set up. Deactivating and reactivating resets cameras back to their starting position. Alternately you could have the Moving Camera's flags set to dormant and eliminate the need for the initial Thing_Deactivate statement since it will already be deactiavted. It is important with ChangeCamera that the TID to view from is the Moving Camera thing and not any of the interpolation points. In this case, the camera to view is TID 2. I only want it to effect 1 player since I only have 1 starting position in the map so I left the second argument at 0. The third argument has been set to 1 so that the view switches back to the player when movement occurs. Save the map, build all the nodes, and check it out.

For the next example, I decided to have a bit more fun. I'm sure everyone has seen The Matrix (or if not, played Max Payne) and is familiar with it's "Bullet Time" effect. What you may not know is that you can do something similar to it in ZDoom with some ACS trickery and a moving camera. This example will rely on the example wad, CAMEX2.WAD, a bit more than the previous example as the values that I will provide in this example are calculated based on the distances I have set up in the wad.
This example is all about illusion. Using an OPEN script and a Thing_Projectile statement using slow movement rates, I fire a rocket from where the player is, thus entering "bullet time." The player is stuck in some impassable lines and as a result can't move. I change the camera before I fire the rocket. From there, the camera goes along it's path following the rocket and getting nice and close to the imp before the rocket explodes. It swings right up to another camera angle when the rocket explodes so that you may see the imp fly off - a return to "real time." You will notice that the camera and the first two interpolation points all have the same X, Y, and Z values. This is to help counter a flicker effect you sometimes get when switching to moving cameras. The path is not looping and as a result the last node has all its arguments set to 0.

These aren't the only way in which you can use cameras. You can set up cut scenes with dialogue using cameras and some print or hudmsg statements. Refer to Doom - The Arcade game for examples on a possible way this can be done.

I may make more examples if there is sufficient demand, but for now those two examples should keep you occupied and give you an idea of what you can do with cameras in ZDoom maps.


Section 4: Increasing the longevity of your maps.

Making a memorable map will only get you so far if the path is linear and the only variation in skill levels is the amount of enemies thrown at the player. With time, planning, and a healthy dose of scripting, you can increase the replayability factor of your map and make people demand more. Just some of the things you can do are:

- Close off sections of the map. You can close off an especially hard area of the map in lower difficulty levels, and when the player gets enough confidence to try a harder difficulty level he/she will be surprised to find additional areas open.
- Enhance the story. If your maps follow a story, make it understandable in the easiest difficulty, expand on it a bit more in a medium difficulty, and give the player the full story in a hard difficulty. Since ACS is able to discriminate between the five difficulty modes, you could reward the insane players who only play nightmare with really juicy parts of the story, and it might even entice players to attempt nightmare just to see what the big fuss is all about.
- Multiple paths. Especially cool if you cross the paths and allow the player to switch paths at the intersection, which will give the player countless ways to play through the map (well, ok, not countless, but you get the point). Related to this are multiple exits which deposit you at different starting positions in the next map.
- Multiple solutions to a problem. Some players will enjoy finding more than one solution to a problem, and for the players that don't enjoy that they could probably find a solution easilly which compliments their play style. I have started to delve in to this area with the reactor in MAP01 of Doom - The Arcade Game. In it, you can rupture the coolant pipes to cause an overload, or you can interact with a computer to drain the coolant tanks and cause an overload that way. Speaking of which...
- Experiment. The computer in Doom - The Arcade Game was an experiment I had in mind for another project of mine called The Doom Chronicles. Thankfully it worked well, but unfortunately thanks to the limited interface of Doom I wasn't able to quite do it as well as I would have liked. Of course, your entire map could be one huge experiment, like MAP90 of Doom - The Arcade Game.
- Secrets. If you make them devilishly hard to find, make sure they're something the player can say "hey, there was a logic to how I found that secret" in retrospect. An example would be in my Doom Chronicles Chapter 4 WIP. To get to a soulsphere in the warehouse, you had to attack a stack of crates with a weapon (a chainsaw works best). When it gets hit enough, it lowers, simulating one of the crates collapsing in on itself and the ones on top crushing the one collapsing. The crate was now at a good jumping height, and you were able to collect the soul sphere.
- DeHackEd. Give the player something different. I am using several dead body things and the SS Soldier as Marines that the player can interact with (with additional help from some scripting) in Doom - The Arcade Game. Changing the dead body things could mean less decorations for your map. This is fine if you don't need dead bodies, but if you do, an open script to kill monsters with a certain TID will give you all the dead bodies you'll ever need. A Super Duper Wowee Zowie 5000-shells-a-minute Shotgun isn't the greatest DeHackEd patch in the world as it takes alot of the difficulty away from the game (you could kill a Cyberdemon without thinking with one of those things).


Section 5: Advanced stuff

I will explain just how I made starbox.wad in this section. You can obtain the wad from http://zdoom.notgod.com/ftp/gooberman/starbox.zip.
Starbox (or by it's real name, Docking Sequence) utilises skyboxes. Skyboxes are easy enough to set up - set up a section of your map separate from the rest of the map to have what you want to view in the skybox and include a Skybox (thing 9080) thing inside of the area. Any uses of skyboxes in your map will use this point to view the skybox from. You can assign Skybox things a TID if you wish to have multiple skyboxes per map. Stick a Skybox Viewer (Thing 9081) thing inside a sector which has F_SKY1 as a flat, set it's first argument to that of the TID of the Skybox you wish to view from, and the sector will use the skybox as it's sky. Because Skyboxes can be assigned a TID, this leaves the way open for it to be controlled with an Actor Mover thing. Set the Actor Mover's argument 4 to the TID of the Skybox, assign the Actor Mover a TID, set up an interpolation path, and tell the Actor Mover to use the first point of the interpolation path as the first point in it's path. It is important to note that the Skybox and not the Actor Mover needs to have it's flags set to Dormant. The Actor Mover will not work if the map is loaded and the Skybox is not dormant. Utilising an OPEN script, activate the Actor Mover, not the Skybox. It is a bit confusing in regards to the Skybox being dormant but the Thing_Activate special activating the Actor Mover, but once you get past that confusion you can do some real cool stuff with skyboxes, like the docking sequence that starbox demonstrates.


Appendix 1: Links

ZDoom: http://zdoom.notgod.com
ZDoom Knowledge Base: http://zdoom.notgod.com/zdkb
Doom - The Arcade Game: http://www.doomworld.com/doomarcade
Doom Chronicles: http://www.geocities.com/gooberman_and_friends/doom_chronicles


Appendix 2: Credits

This entire document and all example wads were written/created by Ethan Watson AKA GooberMan.
I referred to the ZDoom Technical Reference and some text files written by Randy Heit outlining the usage and implementation of cameras and skyboxes while writing this article. All the files I referred to are available from the ZDoom website.
Utilites used in the creation of this tutorial are Notepad, by Microsoft; and ZETH, a version of the Doom level editor DETH tweaked to take advantage of the new ZDoom features.


Appendix 3: Thanks go to...

This tutorial wouldn't exist if Randy Heit didn't implement all the features discussed in this article to his ZDoom source port, so a big thanks goes out to him.
Nigel Rowland AKA Enjay suggested that I should write up a tutorial explaining how to use moving cameras after seeing my Doom - The Arcade game mod and the Docking Sequence, so thanks also goes out to him. Now I have something easier to read to refer to when I'm implementing cameras in my maps :)